
	Concentre.XForms_Binding = Concentre.Class(Object, {
		properties: {},
		controls: [],
		innerBindings:[],
		
		initialize: function (node, model, parent) {
		
			this.model = model;
			this.target = node;
			this.parent = parent;
			this.controls = [];
			this.properties = {};
			this.innerBindings = [];
			
			this.parent.innerBindings.unshift(this);
									
			var attrs = this.target.attributes;
						
			for (var i = attrs.length; --i>=0; ) {
				var attr = attrs[i];
					switch (attr.nodeName) {
						case 'nodeset':
						case 'ref':
							this.type = i;
							this.xpath = attr.nodeValue;
							break;
						case 'id':
							this.id = attr.nodeValue;
							break;
						case 'relevant':
						case 'readonly':
						case 'required':
						case 'constraint':
						case 'calculate':
							this.properties[ attr.nodeName ] = attr.nodeValue;	
							break;
						case 'type':
							this.datatype = QName.toHash(attr.nodeValue);
							break;
					}
			}

			if (this.properties['calculate'] && !this.properties['readonly']) { this.properties['readonly']='true()'; 	}

		},
		
		build : function (boundContext) {

		var m = this.model;
		
		if (!this.xpath && this.properties['calculate']) {

		var valueNode = document.createElement("output-value");

		var boundVertex = m.graph.addVertex( valueNode, 'text', boundContext, null);		
		boundVertex.controls = boundVertex.controls.concat(this.controls);
		
		var expr = new XPath(this.properties[ 'calculate' ]);
		
		var vertex = m.graph.addVertex( valueNode, 'calculate', boundContext, expr);

		expr(boundContext, QName);
		var references = XPath.referencednodes;
		
		for (var j = references.length; --j>=0; ) {
			vertex.dependsOn(m.graph.addVertex(references[j], "text"));
    	}
        
		boundVertex.dependsOn(vertex);
		
		for (var i = boundVertex.dependents.length; --i>=0; ) {
			  if (boundVertex.dependents[i].node === boundVertex.node)	boundVertex.dependents[i].controls = boundVertex.controls;
		}
							
		return;
		}
	
		var expr = new XPath( this.xpath );
		var nodeset = expr(boundContext, QName);

		/*
		console.log (this.xpath);
		console.log(nodeset);
		*/		
		
	if (nodeset.length == 0) {
		throw new Exception('IDS_XFORMS_BINDING_EXCEPTION');
		
		/*for (var i in this.controls) {
			this.controls[i].setProperty('relevant',false);
		}*/
		
	}
	
	
	this.boundNodes = nodeset;
	this.boundContext = boundContext;	

	for (var i=this.controls.length; --i >= 0;) {
		this.controls[i].build(this,nodeset);
	}

	for (var i = nodeset.length; --i>=0; ) {

		var n = nodeset[i];
  		var c = n;

		var boundVertex = m.graph.addVertex( n, 'text', boundContext, null);
		boundVertex.controls = boundVertex.controls.concat(this.controls);
		/*
		var v1 = m.graph.getVertex( n, 'type', c);
		if (v1!=null) {
			this.datatype = v1.xpath;
		} else {
			//if (this.datatype==null) this.datatype = Qnames.resolve(concentre.factory.domutils.getAttributeNS('http://www.w3.org/2001/XMLSchema-instance','type', n));
			if (this.datatype!=null) {
				var v1 = m.graph.addVertex( n, 'type', c, this.datatype);
				v1.dependsOn(boundVertex);
			}
		}		
		*/
			
		for (var property in this.properties) {

			if (!this.properties[property]) continue;

			var expr = new XPath(this.properties[ property ]);
            var vertex = m.graph.addVertex( n, property, c, expr);
           
			expr(c, QName);
			var references = XPath.referencednodes;
			
			for (var j = references.length; --j>=0; ) {
				vertex.dependsOn(m.graph.addVertex(references[j], "text"));
			}

			if (property=='calculate') {
				boundVertex.dependsOn(vertex);
			} else {
		        vertex.dependsOn(boundVertex);
 			}

		}	
		
		}
		
		
		for (var i = boundVertex.dependents.length; --i>=0; ) {
			  var deps = boundVertex.dependents[i];
			  if (deps.node === boundVertex.node) deps.controls = boundVertex.controls;
		}

			for (var j = this.innerBindings.length; --j>=0;) {
				this.innerBindings[j].build(c);
	  		}
		
		},
		
		toString: function() {
			return '[ Object Concentré XForms Binding ]';
		}
		
	});
